package cn.mesmile.thread.aqs;

import lombok.extern.slf4j.Slf4j;
import sun.misc.Unsafe;

import java.util.concurrent.BrokenBarrierException;
import java.util.concurrent.CyclicBarrier;

/**
 * @author zb
 * @date 2021/5/30 19:27
 * @Description:
 */
@Slf4j
public class ThreadAQS {

    private volatile int state = 0;

    private  static long stateOffset;

    private static final Unsafe unsafe = UnsafeInstance.reflectGetUnsafe();

    private static CyclicBarrier cyclicBarrier = new CyclicBarrier(5);

    private static ThreadAQS cas = new ThreadAQS();


    public static void main(String[] args) {
        new Thread(new Worker(),"t-0").start();
        new Thread(new Worker(),"t-1").start();
        new Thread(new Worker(),"t-2").start();
        new Thread(new Worker(),"t-3").start();
        new Thread(new Worker(),"t-4").start();
    }

    static class Worker implements Runnable{
        @Override
        public void run() {
            log.info(">>>>>>>> 请求: {} 到达预定点，准备开始抢 state：", Thread.currentThread().getName());
            try {
                cyclicBarrier.await();
                if (cas.compareAndSwapState(0, 1)) {
                    log.info(">>>>>>>> 当前请求： {} , 抢到锁！",Thread.currentThread().getName());
                } else {
                    log.info(">>>>>>>> 当前请求： {} , 抢锁失败！",Thread.currentThread().getName());
                }
            } catch (Exception e) {
                e.printStackTrace();
            }
        }
    }

    /**
     *
     * @param oldValue 旧的值
     * @param newValue 新的值
     * @return
     */
    public final boolean compareAndSwapState(int oldValue, int newValue){
        return unsafe.compareAndSwapInt(this, stateOffset,oldValue,newValue);
    }

    static {
        try {
            stateOffset = unsafe.objectFieldOffset(ThreadAQS.class.getDeclaredField("state"));
        } catch (NoSuchFieldException e) {
            e.printStackTrace();
        }
    }
}
